package me.aartikov.alligator.converters;


import me.aartikov.alligator.Screen;
import me.aartikov.alligator.helpers.MiFraction;
import ohos.aafwk.content.IntentParams;
import ohos.utils.Sequenceable;

import java.io.Serializable;


/**
 * Creates a fragment of the given class. It also puts a screen to the fragment's arguments if {@code ScreenT} is {@code Serializable} or {@code Parcelable}.
 *
 * @param <ScreenT> screen type
 */

public class DefaultFragmentConverter<ScreenT extends Screen> implements FragmentConverter<ScreenT> {
    public static final String KEY_SCREEN = "me.aartikov.alligator.KEY_SCREEN";

    private Class<ScreenT> mScreenClass;
    private Class<? extends MiFraction> mFragmentClass;

    public DefaultFragmentConverter(Class<ScreenT> screenClass, Class<? extends MiFraction> fragmentClass) {
        mScreenClass = screenClass;
        mFragmentClass = fragmentClass;
    }

    @Override
    public MiFraction createFragment(ScreenT screen) {
        try {
            MiFraction fragment = (MiFraction) mFragmentClass.newInstance();
            IntentParams arguments = fragment.getIntentParams();
            if (arguments == null) {
                arguments = new IntentParams();
            }
            arguments.setParam(KEY_SCREEN, screen);
            fragment.setIntentParams(arguments);

//            if (screen instanceof Serializable) {
//                if (arguments == null) {
//                    arguments = new IntentParams();
//                }
//                arguments.setParam(KEY_SCREEN, (Serializable) screen);
//                fragment.setIntentParams(arguments);
//            } else if (screen instanceof Sequenceable) {
//                if (arguments == null) {
//                    arguments = new IntentParams();
//                }
//                arguments.setParam(KEY_SCREEN, (Sequenceable) screen);
//                fragment.setIntentParams(arguments);
//            }

// 			if (screen instanceof Serializable) {
//				Bundle arguments = new Bundle();
//				arguments.putSerializable(KEY_SCREEN, (Serializable) screen);
//				fragment.setArguments(arguments);
//			} else if (screen instanceof Parcelable) {
//				Bundle arguments = new Bundle();
//				arguments.putParcelable(KEY_SCREEN, (Parcelable) screen);
//				fragment.setArguments(arguments);
//			}
            return fragment;
        } catch (InstantiationException e) {
            throw new RuntimeException("Failed to create a fragment", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to create a fragment", e);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public ScreenT getScreen(MiFraction fragment) {
//        if (fragment.getFractionAbility().getIntent() == null) {
//            throw new IllegalArgumentException("Fragment has no arguments.");
//        } else
        if (Serializable.class.isAssignableFrom(mScreenClass)) {
            Object ob = fragment.getIntentParams().getParam(KEY_SCREEN);
            return checkNotNull((ScreenT) ob);
        } else if (Sequenceable.class.isAssignableFrom(mScreenClass)) {
            return checkNotNull((ScreenT) fragment.getIntentParams().getParam(KEY_SCREEN));
        } else {
            throw new IllegalArgumentException("Screen " + mScreenClass.getSimpleName() + " should be Serializable or Parcelable.");
        }
    }

    private ScreenT checkNotNull(ScreenT screen) {
        if (screen == null) {
            throw new IllegalArgumentException("Failed to get screen from arguments of fragment.");
        }
        return screen;
    }
}
